package pe.com.itworth.ttsclient.infrastructure;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Properties;

import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.search.ComparisonTerm;
import javax.mail.search.ReceivedDateTerm;
import javax.mail.search.SearchTerm;

import pe.com.itworth.ttsclient.controller.AccountsMenuController;
import pe.com.itworth.ttsclient.shared.AccountInfoDTO;
import pe.com.itworth.ttsclient.shared.FolderAndMailsDTO;
import pe.com.itworth.ttsclient.shared.FolderInfoDTO;
import pe.com.itworth.ttsclient.shared.MailDTO;
import pe.com.itworth.ttsclient.util.FechaFactory;
import pe.com.itworth.ttsclient.util.FechaUtilitario;

import android.database.Cursor;


public class MailMannagerGMAILImpl implements MailManager {

	private AccountInfoDTO accountInfoDTO;
	private MailReader mailReader;

	public MailMannagerGMAILImpl(AccountInfoDTO accountInfoDTO,
			MailReader mailReader) {
		super();
		this.accountInfoDTO = accountInfoDTO;
		this.mailReader = mailReader;
	}

	@Override
	public Collection<MailDTO> downloadMails(FolderInfoDTO folderInfo)
			throws NoSuchProviderException, MessagingException {
		Collection<MailDTO> mails = new ArrayList<MailDTO>();
		
		Properties props = new Properties();

		Session session = Session.getDefaultInstance(props, null);
		Store store = session.getStore(accountInfoDTO.getsProvider());
		store.connect(accountInfoDTO.getsHost(), accountInfoDTO.getsUsername(),
				accountInfoDTO.getsPassword());

		Folder folder = store.getFolder(folderInfo.getsName());
		
		int ii = Folder.HOLDS_FOLDERS;
		if (folder.getType() != ii) {
			folder.open(Folder.HOLDS_FOLDERS);

			Date dLastDate = FechaFactory.crearFecha(1000, 1, 1);
			Cursor c = AccountsMenuController.myDbHelper
					.executeQuery("select max(m.d_date) as last_date from mail m inner join folder f "
							+ "on m.i_id_folder = f.i_id "
							+ "inner join account a "
							+ "on f.i_id_account = a.i_id where f.t_name like '"
							+ folderInfo.getsName()
							+ "' "
							+ "and a.t_username like '"
							+ accountInfoDTO.getsUsername() + "'");
			if (c != null) {
				if (c.getCount() > 0) {
					c.moveToFirst();
					String sDate = c.getString(c.getColumnIndex("last_date"));
					if (sDate != null)
						dLastDate = FechaUtilitario.deCadenaAFecha(sDate);
				}
			}
			SearchTerm newer = new ReceivedDateTerm(ComparisonTerm.GT,
					dLastDate);
			Message[] messages = folder.search(newer);

			for (int i = 0; i < messages.length; i++) {
				mails.add(mailReader.read(messages[i]));
			}

		}
		
		folder.close(false);
		store.close();

		return mails;
	}

	@Override
	public Collection<FolderAndMailsDTO> downloadFoldersWithMails()
			throws NoSuchProviderException, MessagingException {
		Collection<FolderAndMailsDTO> foldersAndMails = new ArrayList<FolderAndMailsDTO>();
		Properties props = new Properties();

		Session session = Session.getDefaultInstance(props, null);
		Store store = session.getStore(accountInfoDTO.getsProvider());
		store.connect(accountInfoDTO.getsHost(), accountInfoDTO.getsUsername(),
				accountInfoDTO.getsPassword());

		Folder[] folders = store.getDefaultFolder().list();

		for (Folder folder : folders) {
			FolderAndMailsDTO newFolder = getFolderWithMails(folder);
			foldersAndMails.add(newFolder);
		}

		store.close();

		return foldersAndMails;
	}

	private FolderAndMailsDTO getFolderWithMails(Folder folder) throws MessagingException {
		FolderAndMailsDTO newFolder = new FolderAndMailsDTO();

		newFolder.setsName(folder.getName());
		Collection<MailDTO> mails = new ArrayList<MailDTO>();

		int ii = Folder.HOLDS_FOLDERS;
		if (folder.getType() != ii) {
			folder.open(Folder.HOLDS_FOLDERS);

			Date dLastDate = FechaFactory.crearFecha(1000, 1, 1);
			Cursor c = AccountsMenuController.myDbHelper
					.executeQuery("select max(m.d_date) as last_date from mail m inner join folder f "
							+ "on m.i_id_folder = f.i_id "
							+ "inner join account a "
							+ "on f.i_id_account = a.i_id where f.t_name like '"
							+ folder.getName()
							+ "' "
							+ "and a.t_username like '"
							+ accountInfoDTO.getsUsername()
							+ "'");
			if (c != null) {
				if (c.getCount() > 0) {
					c.moveToFirst();
					String sDate = c.getString(c.getColumnIndex("last_date"));
					if (sDate != null)
						dLastDate = FechaUtilitario.deCadenaAFecha(sDate);
				}
			}
			SearchTerm newer = new ReceivedDateTerm(ComparisonTerm.GT,
					dLastDate);
			Message[] messages = folder.search(newer);

			for (int i = 0; i < messages.length; i++) {
				mails.add(mailReader.read(messages[i]));
			}

			newFolder.setMails(mails);

			folder.close(false);
		}

		for (Folder childFolder : folder.list()) {
			newFolder.getChildFolders().add(
					getFolderWithMails(childFolder));
		}

		return newFolder;
	}

	@Override
	public Collection<FolderInfoDTO> getFolderNames() throws MessagingException, NoSuchProviderException{
		Collection<FolderInfoDTO> folderInfos = new ArrayList<FolderInfoDTO>();
		Properties props = new Properties();

		Session session = Session.getDefaultInstance(props, null);
		Store store = session.getStore(accountInfoDTO.getsProvider());
		store.connect(accountInfoDTO.getsHost(), accountInfoDTO.getsUsername(),
				accountInfoDTO.getsPassword());

		Folder[] folders = store.getDefaultFolder().list();

		for (Folder folder : folders) {
			getFolderInfos(folderInfos, folder);
		}

		return folderInfos;
	}

	private void getFolderInfos(Collection<FolderInfoDTO> folderInfos, Folder folder) throws MessagingException {
		int ii = Folder.HOLDS_FOLDERS;
		if (folder.getType() != ii) {
			FolderInfoDTO newFolder = new FolderInfoDTO();
			newFolder.setsName(folder.getFullName());
			folderInfos.add(newFolder);
		}
		
		for (Folder childFolder : folder.list()) {
			getFolderInfos(folderInfos, childFolder);
		}
	}

}
